package pkg.andru.core;

import java.util.HashMap;
import java.util.Stack;

import pkg.andru.R;
import android.content.Intent;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;

/**
 * 
 * @author idiottiger
 * 
 */
public class CommonFragmentManager {

    static final String TAG = "CommonFragmentManager";

    private FragmentManager mFragmentManager;
    private CommonFragment mCurrentFragment;
    private FragmentActivity mActivity;

    private Stack<CommonFragment> mFragmentsStack;
    private int mContainerId;

    private HashMap<String, Intent> mPassIntentMap = null;

    int mAnimIn = R.anim.slide_right_in_frag, mAnimOut = R.anim.slide_left_out_frag, mAnimPopIn = R.anim.slide_left_in_frag, mAnimPopOut = R.anim.slide_right_out_frag;

    boolean mAnimeEnable;

    CommonFragmentManager(FragmentActivity activity) {
        mActivity = activity;
        mFragmentsStack = new Stack<CommonFragment>();
        mFragmentsStack.clear();

        mPassIntentMap = new HashMap<String, Intent>();
    }

    public void setFragmentContainerLayoutId(int container) {
        mContainerId = container;
    }

    private void initFragmentManager() {
        if (mFragmentManager == null) {
            mFragmentManager = mActivity.getSupportFragmentManager();
        }
    }

    public void setFragmentAnimationEnable(boolean enable) {
        mAnimeEnable = enable;
    }

    public void setFragmentAnimation(int in, int out, int popIn, int popOut) {
        mAnimIn = in;
        mAnimOut = out;
        mAnimPopIn = popIn;
        mAnimPopOut = popOut;
    }

    public FragmentManager getFragmentManager() {
        initFragmentManager();
        return mFragmentManager;
    }

    public void addFragmentToBackStack(CommonFragment fragment, String tag, boolean isFirstFragment) {
        initFragmentManager();
        FragmentTransaction transaction = mFragmentManager.beginTransaction();
        if (mAnimeEnable) {
            transaction.setCustomAnimations(isFirstFragment ? 0 : mAnimIn, isFirstFragment ? 0 : mAnimOut, mAnimPopIn, mAnimPopOut);
        }
        transaction.replace(mContainerId, fragment, tag);
        transaction.addToBackStack(tag);

        fragment.setFragmentTag(tag);

        try {
            transaction.commit();
            mFragmentsStack.push(fragment);
        } catch (Exception e) {
            e.printStackTrace();
        }

        setCurrentFragment(fragment);
    }

    public boolean popBackStackFragment() {
        initFragmentManager();
        boolean result = false;
        int size = mFragmentsStack.size();
        if (size >= 1) {
            if (size == 1) {
                return false;
            }
            mFragmentsStack.pop();
            result = !mFragmentsStack.isEmpty();
            mFragmentManager.popBackStack();
            mCurrentFragment = result ? mFragmentsStack.peek() : null;
        }
        return result;
    }

    public void popBackStackFragment(String tag) {
        initFragmentManager();
        Log.i(TAG, "popBackStackFragment: tag " + tag);
        int size = mFragmentsStack.size();
        if (size >= 1) {
            int index = 0;
            for (CommonFragment fragment : mFragmentsStack) {
                if (fragment.getFragmentTag().equalsIgnoreCase(tag)) {
                    break;
                }
                index++;
            }

            // mean found
            if (index != size) {
                // pop
                int count = size - index;
                for (int i = 0; i < count; i++) {
                    mFragmentsStack.pop();
                }
                mFragmentManager.popBackStackImmediate(tag, FragmentManager.POP_BACK_STACK_INCLUSIVE);
                mCurrentFragment = index == 0 ? null : mFragmentsStack.peek();
            }
        }
    }

    public void setCurrentFragment(CommonFragment fragment) {
        mCurrentFragment = fragment;
    }

    public CommonFragment getCurrentFragment() {
        return mCurrentFragment;
    }

    public void passIntent(String key, Intent intent) {
        mPassIntentMap.remove(key);
        mPassIntentMap.put(key, new Intent(intent));
    }

    public Intent getPassIntent(String key) {
        Intent get = mPassIntentMap.get(key);
        Intent result = null;
        if (get != null) {
            result = new Intent(get);
        }
        mPassIntentMap.remove(key);
        return result;
    }

    public void clearPassIntent(String key) {
        mPassIntentMap.remove(key);
    }

    public void release() {
        mFragmentManager = null;
        mCurrentFragment = null;
        if (mFragmentsStack != null) {
            mFragmentsStack.clear();
        }
        if (mPassIntentMap != null) {
            mPassIntentMap.clear();
        }
        mActivity = null;
    }
}
